// The following functions are from threejs: https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderChunk/packing.glsl.js

vec3 packNormalToRGB(const in vec3 normal) {
    return normalize(normal) * 0.5 + 0.5;
}
vec3 unpackRGBToNormal(const in vec3 rgb) {
    return 2.0 * rgb.xyz - 1.0;
}
const float PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1)
const float UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1)
const vec3 PackFactors = vec3(256. * 256. * 256., 256. * 256., 256.);
const vec4 UnpackFactors = UnpackDownscale / vec4(PackFactors, 1.);
const float ShiftRight8 = 1. / 256.;
vec4 packDepthToRGBA(const in float v) {
    vec4 r = vec4(fract(v * PackFactors), v);
    r.yzw -= r.xyz * ShiftRight8; // tidy overflow
    return r * PackUpscale;
}
float unpackRGBAToDepth(const in vec4 v) {
    return dot(v, UnpackFactors);
}
vec2 packDepthToRG(in highp float v) {
    return packDepthToRGBA(v).yx;
}
float unpackRGToDepth(const in highp vec2 v) {
    return unpackRGBAToDepth(vec4(v.xy, 0.0, 0.0));
}
vec4 pack2HalfToRGBA(vec2 v) {
    vec4 r = vec4(v.x, fract(v.x * 255.0), v.y, fract(v.y * 255.0));
    return vec4(r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w);
}
vec2 unpackRGBATo2Half(vec4 v) {
    return vec2(v.x + (v.y / 255.0), v.z + (v.w / 255.0));
}
// NOTE: viewZ/eyeZ is < 0 when in front of the camera per OpenGL conventions
float viewZToOrthographicDepth(const in float viewZ, const in float near, const in float far) {
    return (viewZ + near) / (near - far);
}
float orthographicDepthToViewZ(const in float linearClipZ, const in float near, const in float far) {
    return linearClipZ * (near - far) - near;
}
// NOTE: https://twitter.com/gonnavis/status/1377183786949959682
float viewZToPerspectiveDepth(const in float viewZ, const in float near, const in float far) {
    return ((near + viewZ) * far) / ((far - near) * viewZ);
}
float perspectiveDepthToViewZ(const in float invClipZ, const in float near, const in float far) {
    return (near * far) / ((far - near) * invClipZ - far);
}